home *** CD-ROM | disk | FTP | other *** search
- Path: mail2news.demon.co.uk!genesis.demon.co.uk
- From: Lawrence Kirby <fred@genesis.demon.co.uk>
- Newsgroups: comp.lang.c
- Subject: Re: my atoi function, could someone suggest...
- Date: Sat, 13 Jan 96 22:45:57 GMT
- Organization: none
- Message-ID: <821573157snz@genesis.demon.co.uk>
- References: <4cf7ap$q4u@kaleka.seanet.com> <4cq937$if9@ns.RezoNet.NET> <4d6v51$qoh@gryphon.phoenix.net>
- Reply-To: fred@genesis.demon.co.uk
- X-NNTP-Posting-Host: genesis.demon.co.uk
- X-Newsreader: Demon Internet Simple News v1.27
- X-Mail2News-Path: genesis.demon.co.uk
-
- In article <4d6v51$qoh@gryphon.phoenix.net>
- brucew@phoenix.net "Bruce Wedding" writes:
-
- >ray@ultimate-tech.com (Ray Dunn) wrote:
- >
- >How about this version:
- >
- >int atoi(char *s)
-
- The standard atoi function takes an argument of type const char *. It is
- sensible for a user function to do the same when it doesn't modify what
- is being pointed at.
-
- >{
- > int i, n, sign;
- >
- > for ( i = 0; s[i] == ' ' || s[i] == '\n' || s[i] == '\t'; i++);
- > /* skip white space */
-
- The standard atoi is defined in terms of leading white-space as defined
- by isspace(). Therefore it is probably more correct (as well as possibly
- more efficient) to use this.
-
- As a matter of style I suggest you avoid terminating a for statement with
- a ; on the same line as the for itself - this is too easy to overlook.
-
- > sign = 1;
- > if ( s[i] == '+' || s[i] == '-')
- > sign = (s[i++] == '+') ? 1 : -1;
-
- This could probably be simplified.
-
- > for (n = 0; s[i] >= '0' && s[i] <= '9'; i++)
- > n = 10 * n + s[i] - '0';
- > return(sign * n);
-
- This could have problems with INT_MIN whose magnitude can be greater than
- INT_MAX.
-
- >}
-
- I give the following as an example of some alternative approaches.
- Ray's code in particular is good, and some may prefer it.
-
- #include <ctype.h>
-
- int myatoi(const char *str)
-
- {
- int negative;
-
- while (isspace(*str))
- str++;
-
- switch (*str) {
- case '-':
- str++;
- negative = 1;
- break;
- case '+':
- str++;
- /* Continues */
- default:
- negative = 0;
- break;
- }
-
- {
- unsigned value = 0;
- unsigned digit = *str - '0';
-
- if (digit < 10) {
- value = digit;
-
- while ((digit = *++str - '0') < 10)
- value = value * 10 + digit;
- }
-
- return (negative && value != 0) ? -(int)(value-1)-1 : (int)value;
- }
- }
-
- The assumptions here are that the magnitude of INT_MIN is no larger than
- UINT_MAX and also no larger than INT_MAX+1.
-
- It is interesting to note in passing that on my particular system the return
- expression compiles to simply:
-
- testl %esi,%esi
- je .L17
- testl %eax,%eax
- je .L17
- negl %eax
- .L17
-
- so it isn't as bad as it first looks! :-)
-
- --
- -----------------------------------------
- Lawrence Kirby | fred@genesis.demon.co.uk
- Wilts, England | 70734.126@compuserve.com
- -----------------------------------------
-